home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / omega / ogen1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-08-06  |  17.0 KB  |  614 lines

  1. /* omega copyright (c) 1987,1988 by Laurence Raphael Brothers */
  2. /* ogen1.c */
  3. /* level generator functions */
  4.  
  5. #include "oglob.h"
  6.  
  7.  
  8. /* bv access functions for dungeon location stati */
  9. int loc_statusp(x,y,stat)
  10. int x,y;
  11. int stat;
  12. {
  13.   return(Level->site[x][y].lstatus & stat);
  14. }
  15.  
  16. void lset(x,y,stat)
  17. int x,y;
  18. int stat;
  19. {
  20.  Level->site[x][y].lstatus |= stat;
  21. }
  22.  
  23. void lreset(x,y,stat)
  24. int x,y;
  25. int stat;
  26. {
  27.   Level->site[x][y].lstatus &= ~stat;
  28. }
  29.  
  30.  
  31.  
  32. /* Deallocate current dungeon */
  33. void free_dungeon()
  34. {
  35.   plv tlv;
  36.   
  37.   while (Dungeon != NULL) {
  38.     tlv = Dungeon;
  39.     Dungeon = Dungeon->next;
  40.     free((char *) tlv);
  41.   }
  42. }
  43.  
  44.  
  45. /* erase the level w/o deallocating it*/
  46. void clear_level(dungeon_level)
  47. struct level *dungeon_level;
  48. {
  49.   int i,j;
  50.   if (dungeon_level != NULL) {
  51.     dungeon_level->generated = FALSE;
  52.     dungeon_level->numrooms = 0;
  53.     dungeon_level->tunnelled = 0;
  54.     dungeon_level->mlist = NULL;
  55.     for(i=0;i<MAXWIDTH;i++)
  56.       for(j=0;j<MAXLENGTH;j++) {
  57.     dungeon_level->site[i][j].locchar = WALL;
  58.     dungeon_level->site[i][j].showchar = ' ';
  59.     dungeon_level->site[i][j].creature = NULL;
  60.     dungeon_level->site[i][j].things = NULL;
  61.     dungeon_level->site[i][j].aux = difficulty()*20;
  62.     dungeon_level->site[i][j].buildaux = 0;
  63.     dungeon_level->site[i][j].p_locf = L_NO_OP;
  64.     dungeon_level->site[i][j].lstatus = 0;
  65.     dungeon_level->site[i][j].roomnumber = RS_WALLSPACE;
  66.       }
  67.   }
  68. }
  69.  
  70.  
  71.  
  72. /* Looks for level tolevel in current dungeon which is named by
  73. Dungeon, which may be NULL. If the level is found, and rewrite_level
  74. is FALSE, and the level has already been generated, nothing happens
  75. beyond Level being set correctly. Otherwise the level is recreated
  76. from scratch */
  77.  
  78. void change_level(fromlevel,tolevel,rewrite_level)
  79. char fromlevel,tolevel,rewrite_level;
  80. {
  81.   struct level *thislevel = NULL;
  82.   Player.sx = -1; Player.sy = -1; /* sanctuary effect dispelled */
  83.   thislevel = findlevel(Dungeon,tolevel);
  84.   if (Dungeon != NULL) {
  85.     Dungeon->deepest = max(Dungeon->deepest,tolevel);
  86.     Level->deepest = Dungeon->deepest;
  87.   }
  88.   if (thislevel == NULL) {
  89.     thislevel = ((plv) malloc(sizeof(levtype)));
  90.     clear_level(thislevel);
  91.     Level = thislevel;
  92.     Level->next = Dungeon;
  93.     Dungeon = Level;
  94.   }
  95.   Level = thislevel;
  96.   if ((! Level->generated) || rewrite_level) {
  97.     Level->environment = Current_Environment;
  98.     Level->depth = tolevel;
  99.     Level->generated = TRUE;
  100.     switch(Current_Environment) {
  101.     case E_CAVES: 
  102.       if ((random_range(4)==0) && (tolevel < MaxDungeonLevels))
  103.     room_level();
  104.       else cavern_level();
  105.       break;
  106.     case E_SEWERS: 
  107.       if ((random_range(4)==0) && (tolevel < MaxDungeonLevels))
  108.     room_level();
  109.       else sewer_level(); 
  110.       break;
  111.     case E_CASTLE:
  112.       room_level();
  113.       break;
  114.     case E_ASTRAL:
  115.       maze_level();
  116.       break;
  117.     case E_VOLCANO:
  118.       switch(random_range(3)) {
  119.       case 0: cavern_level(); break;
  120.       case 1: room_level(); break;
  121.       case 2: maze_level(); break;
  122.       }
  123.       break;
  124.     default: print3("This dungeon not implemented!"); break;
  125.     }
  126.     Level->deepest = tolevel;
  127.     install_traps();
  128.     install_specials();
  129.     make_stairs(fromlevel);
  130.     make_stairs(fromlevel);
  131.   }
  132.   find_stairs(fromlevel,tolevel);
  133.   erase_level();
  134.   ScreenOffset = Player.y - (ScreenLength/2);
  135.   show_screen();
  136.   screencheck(Player.y);
  137.   drawvision(Player.x,Player.y);
  138.   /* synchronize with player on level change */
  139.   Player.click = (Tick+1)%60;
  140.   roomcheck();
  141. }
  142.  
  143.  
  144. /* tries to find the level of depth levelnum in dungeon; if can't find
  145.    it returns NULL */
  146. plv findlevel(dungeon,levelnum)
  147. struct level *dungeon;
  148. char levelnum;
  149. {
  150.   if (dungeon == NULL) return(NULL);
  151.   else {
  152.     while((dungeon->next != NULL) && (dungeon->depth != levelnum))
  153.       dungeon = dungeon->next;
  154.     if (dungeon->depth == levelnum) return(dungeon);
  155.     else return(NULL);
  156.   }
  157. }
  158.  
  159.  
  160.  
  161. /* keep going in one orthogonal direction or another until we hit our */
  162. /* destination */
  163.  
  164. void straggle_corridor(fx,fy,tx,ty,loc,rsi)
  165. int fx,fy,tx,ty;
  166. char loc;
  167. char rsi;
  168. {
  169.   int dx,dy;
  170.   while ((fx != tx) || (fy != ty)) {
  171.     dx = tx - fx;
  172.     dy = ty - fy;
  173.     if (random_range(abs(dx)+abs(dy)) < abs(dx))
  174.       corridor_crawl(&fx,&fy,sign(dx),0,random_range(abs(dx))+1,loc,rsi);
  175.     else corridor_crawl(&fx,&fy,0,sign(dy),random_range(abs(dy))+1,loc,rsi);
  176.   }
  177. }
  178.  
  179.  
  180.  
  181. void makedoor(x,y)
  182. int x,y;
  183. {
  184.   if (random_range(20) <= Level->depth/10) {
  185.     Level->site[x][y].locchar = FLOOR;
  186.     lset(x,y,SECRET);
  187.   }
  188.   else if (random_range(20)<=Level->depth/2) {
  189.     Level->site[x][y].locchar = CLOSED_DOOR;
  190.     if (random_range(20) <= Level->depth/10) 
  191.       lset(x,y,SECRET);
  192.     if (random_range(40) <= Level->depth) 
  193.       Level->site[x][y].aux = LOCKED;
  194.     else Level->site[x][y].aux = UNLOCKED;
  195.   }
  196.   else {
  197.     Level->site[x][y].locchar = OPEN_DOOR;
  198.     Level->site[x][y].aux = UNLOCKED;
  199.   }
  200.   if (! loc_statusp(x,y,SECRET)) {
  201.     lset(x,y+1,STOPS);
  202.     lset(x+1,y,STOPS);
  203.     lset(x-1,y,STOPS);
  204.     lset(x,y-1,STOPS);
  205.   }
  206. }
  207.  
  208.  
  209. void corridor_crawl(fx,fy,sx,sy,n,loc,rsi)
  210. int *fx,*fy,sx,sy,n;
  211. char loc,rsi;
  212. {
  213.   int i;
  214.   for (i=0;i<n;i++) {
  215.     *fx += sx;
  216.     *fy += sy;
  217.     if ((*fx < WIDTH) && 
  218.     (*fx > -1) && 
  219.     (*fy > -1) && 
  220.     (*fy < LENGTH)) {
  221.       Level->site[*fx][*fy].locchar = loc;
  222.       if (Level->site[*fx][*fy].roomnumber == RS_WALLSPACE)
  223.     Level->site[*fx][*fy].roomnumber = rsi;
  224.       if (loc==WATER) 
  225.     Level->site[*fx][*fy].p_locf = L_WATER;
  226.       else if (loc==FLOOR) 
  227.     Level->site[*fx][*fy].p_locf = L_NO_OP;
  228.       else if (loc==RUBBLE)
  229.     Level->site[*fx][*fy].p_locf = L_RUBBLE;
  230.     }
  231.   }
  232. }  
  233.  
  234.  
  235.  
  236.  
  237. char *roomname(index)
  238. int index;
  239. {
  240.   switch(index) {
  241.   case RS_ZORCH:strcpy(Str4,"A place zorched by high power magic.");break;
  242.   case RS_COURT:strcpy(Str4,"The Court of the ArchMage."); break;
  243.   case RS_CIRCLE:strcpy(Str4,"The Astral Demesne of the Circle of Sorcerors");
  244.     break;
  245.   case RS_MAGIC_ISLE: strcpy(Str4,"An island positively reeking of magic");
  246.     break;
  247.   case RS_STARPEAK: strcpy(Str4,"Near the oddly glowing peak of a mountain");
  248.     break;
  249.   case RS_VOLCANO: strcpy(Str4,"Deep within the bowels of the earth"); break;
  250.   case RS_HIGHASTRAL: strcpy(Str4,"The High Astral Plane"); break;
  251.   case RS_EARTHPLANE: strcpy(Str4,"The Plane of Earth"); break;
  252.   case RS_WATERPLANE: strcpy(Str4,"The Plane of Water"); break;
  253.   case RS_FIREPLANE: strcpy(Str4,"The Plane of Fire"); break;
  254.   case RS_AIRPLANE: strcpy(Str4,"The Plane of Air"); break;
  255.   case RS_KITCHEN: strcpy(Str4,"A kitchen"); break;
  256.   case RS_BATHROOM: strcpy(Str4,"A bathroom"); break;
  257.   case RS_BEDROOM: strcpy(Str4,"A bedroom"); break;
  258.   case RS_DININGROOM: strcpy(Str4,"A dining room"); break;
  259.   case RS_SECRETPASSAGE: strcpy(Str4,"A secret passage"); break;
  260.   case RS_CLOSET: strcpy(Str4,"A stuffy closet"); break;
  261.   case RS_ARENA: strcpy(Str4,"The Rampart Arena"); break;
  262.   case RS_DROWNED_SEWER: strcpy(Str4,"A water-filled sewer node"); break;
  263.   case RS_DRAINED_SEWER: strcpy(Str4,"An unused sewer node"); break;
  264.   case RS_SEWER_DUCT: strcpy(Str4,"A winding sewer duct"); break;
  265.   case RS_DESTINY: strcpy(Str4,"The Halls of Fate"); break;
  266.   case RS_DRUID: strcpy(Str4,"The Great Henge"); break;
  267.   case RS_HECATE: strcpy(Str4,"The Church of the Far Side"); break;
  268.   case RS_SET: strcpy(Str4,"The Temple of the Black Hand"); break;
  269.   case RS_ATHENA: strcpy(Str4,"The Parthenon"); break;
  270.   case RS_ODIN: strcpy(Str4,"The Shrine of the Noose"); break;
  271.   case RS_ADEPT: strcpy(Str4,"Labyrinth of The Adept's Challenge."); break;
  272.   case RS_WYRM: strcpy(Str4,"The Sunken Cavern of the Great Wyrm."); break;
  273.   case RS_OCEAN: strcpy(Str4,"The Underground Ocean."); break;
  274.   case RS_PONDS: strcpy(Str4,"A series of subterranean pools and streams."); break;
  275.   case RS_DRAGONLORD: strcpy(Str4,"The Lair of the DragonLord."); break;
  276.   case RS_GOBLINKING: strcpy(Str4,"The Caves of the Goblins."); break;
  277.   case RS_CAVERN: strcpy(Str4,"A vast natural cavern."); break;
  278.   case RS_CORRIDOR: strcpy(Str4,"A dimly lit corridor."); break;
  279.   case RS_WALLSPACE: strcpy(Str4,"A niche hollowed out of the wall."); break;
  280.   case ROOMBASE+0: strcpy(Str4,"An abandoned garderobe."); break;
  281.   case ROOMBASE+1: strcpy(Str4,"A dungeon cell."); break;
  282.   case ROOMBASE+2: strcpy(Str4,"A tiled chamber."); break;
  283.   case ROOMBASE+3: strcpy(Str4,"A crystal cavern."); break;
  284.   case ROOMBASE+4: strcpy(Str4,"Someone's bedroom."); break;
  285.   case ROOMBASE+5: strcpy(Str4,"An old storeroom."); break;
  286.   case ROOMBASE+6: strcpy(Str4,"A room with charred walls."); break;
  287.   case ROOMBASE+7: strcpy(Str4,"A marble hall."); break;
  288.   case ROOMBASE+8: strcpy(Str4,"An eerie cave."); break;
  289.   case ROOMBASE+9: strcpy(Str4,"A ransacked treasure-chamber."); break;
  290.   case ROOMBASE+10: strcpy(Str4,"A smoke-filled room."); break;
  291.   case ROOMBASE+11: strcpy(Str4,"A well-appointed apartment."); break;
  292.   case ROOMBASE+12: strcpy(Str4,"An antechamber."); break;
  293.   case ROOMBASE+13: strcpy(Str4,"An unoccupied harem."); break;
  294.   case ROOMBASE+14: strcpy(Str4,"A multi-purpose room."); break;
  295.   case ROOMBASE+15: strcpy(Str4,"A room filled with stalactites."); break;
  296.   case ROOMBASE+16: strcpy(Str4,"An underground greenhouse."); break;
  297.   case ROOMBASE+17: strcpy(Str4,"A water closet."); break;
  298.   case ROOMBASE+18: strcpy(Str4,"A study."); break;
  299.   case ROOMBASE+19: strcpy(Str4,"A living room."); break;
  300.   case ROOMBASE+20: strcpy(Str4,"A comfortable den."); break;
  301.   case ROOMBASE+21: strcpy(Str4,"An abatoir."); break;
  302.   case ROOMBASE+22: strcpy(Str4,"A boudoir.");break;
  303.   case ROOMBASE+23: strcpy(Str4,"A star chamber.");break;
  304.   case ROOMBASE+24: strcpy(Str4,"A manmade cavern."); break;
  305.   case ROOMBASE+25: strcpy(Str4,"A sewer control room");break;
  306.   case ROOMBASE+26: strcpy(Str4,"A shrine to High Magic"); break;
  307.   case ROOMBASE+27: strcpy(Str4,"A magic laboratory"); break;
  308.   case ROOMBASE+28: strcpy(Str4,"A room with inscribed pentagram");break;
  309.   case ROOMBASE+29: strcpy(Str4,"A chamber with a blue crystal omega dais");
  310.     break;
  311.   default: strcpy(Str4,"A room of mystery and allure."); break;
  312.   }
  313.   return(Str4);
  314. }
  315.  
  316.  
  317.  
  318. /* puts the player on the first set of stairs from the apt level */
  319. /* if can't find them, just drops player anywhere.... */
  320. void find_stairs(fromlevel,tolevel)
  321. char fromlevel;
  322. char tolevel;
  323. {
  324.   int i,j,found=FALSE;
  325.   char sitechar;
  326.   if (fromlevel > tolevel) sitechar = DOWN; else sitechar = UP;
  327.   for(i=0;i<WIDTH;i++)
  328.     for(j=0;j<LENGTH;j++) 
  329.       if ((Level->site[i][j].locchar == sitechar) && (! found)) { 
  330.     found = TRUE;
  331.     Player.x = i;
  332.     Player.y = j;
  333.     break;
  334.       }
  335.   if (! found) {
  336.     findspace(&Player.x,&Player.y,-1);
  337.     if (Level->environment != E_ASTRAL)
  338.       Level->site[Player.x][Player.y].locchar = sitechar;
  339.   }
  340. }
  341.  
  342.  
  343.  
  344. void install_traps()
  345. {
  346.   int i,j;
  347.   for(i=0;i<WIDTH;i++)
  348.     for(j=0;j<LENGTH;j++)
  349.       if ((Level->site[i][j].locchar == FLOOR) &&
  350.       (Level->site[i][j].p_locf == L_NO_OP) &&
  351.       random_range(500) <= ((int)(Level->depth/6)))
  352.     Level->site[i][j].p_locf = TRAP_BASE+random_range(NUMTRAPS);
  353. }
  354.  
  355.  
  356.  
  357. /* x, y, is top left corner, l is length of side, rsi is room string index */
  358. /* baux is so all rooms will have a key field. */
  359. void build_square_room(x,y,l,rsi,baux)
  360. int x,y,l;
  361. char rsi;
  362. int baux;
  363. {
  364.   int i,j;
  365.  
  366.   for(i=x;i<=x+l;i++)
  367.     for(j=y;j<=y+l;j++){
  368.       Level->site[i][j].roomnumber = rsi;
  369.       Level->site[i][j].buildaux = baux;
  370.     }
  371.   for(i=x+1;i<x+l;i++)
  372.     for(j=y+1;j<y+l;j++) {
  373.       Level->site[i][j].locchar = FLOOR;
  374.       Level->site[i][j].p_locf = L_NO_OP;
  375.     }
  376. }
  377.  
  378.  
  379.  
  380. void build_room(x,y,l,rsi,baux)
  381. int x,y,l;
  382. char rsi;
  383. int baux;
  384. {
  385.   build_square_room(x,y,l,rsi,baux);
  386. }
  387.  
  388. void cavern_level()
  389. {
  390.   int i,fx,fy,tx,ty,t,l,e;
  391.   char rsi;
  392.  
  393.   Level->numrooms = 1;
  394.  
  395.   if ((Current_Dungeon == CAVES) && (Level->depth == CAVELEVELS))
  396.     rsi = RS_GOBLINKING;
  397.   else rsi = RS_CAVERN;
  398.   t = random_range(LENGTH/2);
  399.   l = random_range(WIDTH/2);
  400.   e = random_range(WIDTH/8)+WIDTH/8;
  401.   build_square_room(t,l,e,rsi,0);
  402.   
  403.   for (i=0;i<16;i++) {
  404.     findspace(&tx,&ty,-1);
  405.     fx = random_range(WIDTH-2)+1;
  406.     fy = random_range(LENGTH-2)+1;
  407.     straggle_corridor(fx,fy,tx,ty,FLOOR,RS_CORRIDOR);
  408.   }
  409.   while (random_range(3)==1) {
  410.     findspace(&tx,&ty,-1);
  411.     fx = random_range(WIDTH-2)+1;
  412.     fy = random_range(LENGTH-2)+1;
  413.     straggle_corridor(fx,fy,tx,ty,WATER,RS_PONDS);
  414.   }
  415.   if (Current_Dungeon == E_CAVES) {
  416.     if ((Level->depth == CAVELEVELS) && (! gamestatusp(COMPLETED_CAVES))) {
  417.       findspace(&tx,&ty,-1);
  418.       Level->mlist = ((pml) malloc(sizeof(mltype)));
  419.       Level->mlist->next = NULL;
  420.       Level->mlist->m = 
  421.     Level->site[tx][ty].creature = 
  422.       ((pmt) make_creature(ML3+5)); /* goblin king */
  423.       Level->mlist->m->x = tx;
  424.       Level->mlist->m->y = ty;
  425.     }
  426.   }
  427.   else if (Current_Environment == E_VOLCANO) {
  428.     if (Level->depth == VOLCANOLEVELS) {
  429.       findspace(&tx,&ty,-1);
  430.       Level->mlist = ((pml) malloc(sizeof(mltype)));
  431.       Level->mlist->next = NULL;
  432.       Level->mlist->m = 
  433.     Level->site[tx][ty].creature = 
  434.       ((pmt) make_creature(ML10+4)); /* The dark emp */
  435.       Level->mlist->m->x = tx;
  436.       Level->mlist->m->y = ty;
  437.     }
  438.   }
  439.   populate_level(Current_Environment);
  440.   stock_level();
  441. }
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449. void sewer_level()
  450. {
  451.   int i,tx,ty,t,l,e;
  452.   char rsi,lchar;
  453.  
  454.   Level->numrooms = random_range(3)+3;
  455.   rsi = RS_DRAINED_SEWER;
  456.   for (i=0;i<Level->numrooms;i++) {
  457.     do {
  458.       t = random_range(LENGTH-10)+1;
  459.       l = random_range(WIDTH-10)+1;
  460.       e = 4;
  461.     } while ((Level->site[l][t].roomnumber == rsi) ||
  462.          (Level->site[l+e][t].roomnumber == rsi) ||
  463.          (Level->site[l][t+e].roomnumber == rsi) ||
  464.          (Level->site[l+e][t+e].roomnumber == rsi));
  465.     if (random_range(5)) {
  466.       lchar = FLOOR;
  467.       rsi = RS_DRAINED_SEWER;
  468.     }
  469.     else {
  470.       lchar = WATER;
  471.       rsi = RS_DROWNED_SEWER;
  472.     }
  473.     build_room(l,t,e,rsi,i);
  474.     sewer_corridor(l,t,-1,-1,lchar);
  475.     sewer_corridor(l+e,t,1,-1,lchar);
  476.     sewer_corridor(l,t+e,-1,1,lchar);
  477.     sewer_corridor(l+e,t+e,1,1,lchar);
  478.   }
  479.   if (Current_Dungeon == E_SEWERS) {
  480.     if ((Level->depth == SEWERLEVELS) && (! gamestatusp(COMPLETED_SEWERS))) {
  481.       findspace(&tx,&ty,-1);
  482.       Level->mlist = ((pml) malloc(sizeof(mltype)));
  483.       Level->mlist->next = NULL;
  484.       Level->mlist->m = 
  485.     Level->site[tx][ty].creature = 
  486.       ((pmt) make_creature(ML7+5)); /* The Great Wyrm */
  487.       Level->mlist->m->x = tx;
  488.       Level->mlist->m->y = ty;
  489.     }
  490.   }
  491.   populate_level(Current_Environment); 
  492.   stock_level();
  493. }
  494.  
  495.  
  496.  
  497. void sewer_corridor(x,y,dx,dy,locchar)
  498. int x,y,dx,dy;
  499. char locchar;
  500. {
  501.   int continuing = TRUE;
  502.   makedoor(x,y);
  503.   x+=dx;
  504.   y+=dy;
  505.   while(continuing) {
  506.     Level->site[x][y].locchar = locchar;
  507.     if (locchar == WATER)
  508.       Level->site[x][y].p_locf = L_WATER;
  509.     else Level->site[x][y].p_locf = L_NO_OP;
  510.     Level->site[x][y].roomnumber = RS_SEWER_DUCT;
  511.     x+=dx;
  512.     y+=dy;
  513.   if (locchar == WATER)
  514.     continuing = (inbounds(x,y) && 
  515.           ((Level->site[x][y].locchar == WALL) ||
  516.            (Level->site[x][y].locchar == WATER)));
  517.   else
  518.     continuing = (inbounds(x,y) && 
  519.           ((Level->site[x][y].roomnumber == RS_WALLSPACE) ||
  520.            (Level->site[x][y].roomnumber == RS_SEWER_DUCT)));
  521.   }
  522.   if (inbounds(x,y))
  523.     makedoor(x,y);
  524. }
  525.  
  526.  
  527.  
  528.  
  529. void install_specials()
  530. {
  531.   int i,j,x,y;
  532.  
  533.   for(x=0;x<WIDTH;x++)
  534.     for(y=0;y<LENGTH;y++)
  535.       if ((Level->site[x][y].locchar == FLOOR) &&
  536.       (Level->site[x][y].p_locf == L_NO_OP) &&
  537.       (random_range(300) < difficulty())) {
  538.     i = random_range(100);
  539.     if (i < 10) {
  540.       Level->site[x][y].locchar = ALTAR;
  541.       Level->site[x][y].p_locf = L_ALTAR;
  542.       Level->site[x][y].aux = random_range(10);
  543.     }
  544.     else if (i < 20) {
  545.       Level->site[x][y].locchar = WATER;
  546.       Level->site[x][y].p_locf = L_MAGIC_POOL;
  547.     }
  548.     else if (i < 35) {
  549.       Level->site[x][y].locchar = RUBBLE;
  550.       Level->site[x][y].p_locf = L_RUBBLE;
  551.     }
  552.     else if (i < 40) {
  553.       Level->site[x][y].locchar = LAVA;
  554.       Level->site[x][y].p_locf = L_LAVA;
  555.     }
  556.     else if (i < 45) {
  557.       Level->site[x][y].locchar = FIRE;
  558.       Level->site[x][y].p_locf = L_FIRE;
  559.     }
  560.     else if ((i < 50) && (Current_Environment != E_ASTRAL)) {
  561.       Level->site[x][y].locchar = LIFT;
  562.       Level->site[x][y].p_locf = L_LIFT;
  563.     }
  564.     else if ((i < 55) && (Current_Environment != E_VOLCANO)) {
  565.       Level->site[x][y].locchar = HEDGE;
  566.       Level->site[x][y].p_locf = L_HEDGE;
  567.     }
  568.     else if (i < 57) {
  569.       Level->site[x][y].locchar = HEDGE;
  570.       Level->site[x][y].p_locf = L_TRIFID;
  571.     }
  572.     else if (i< 70) {
  573.       Level->site[x][y].locchar = STATUE;
  574.       if (random_range(100) < difficulty()) 
  575.         for (j=0;j<8;j++) {
  576.           if (Level->site[x+Dirs[0][j]][y+Dirs[1][j]].p_locf != L_NO_OP)
  577.         Level->site[x+Dirs[0][j]][y+Dirs[1][j]].locchar = FLOOR;
  578.           Level->site[x+Dirs[0][j]][y+Dirs[1][j]].p_locf = 
  579.         L_STATUE_WAKE;
  580.         }
  581.     }
  582.     else {
  583.       if (Current_Environment == E_VOLCANO) {
  584.         Level->site[x][y].locchar = LAVA;
  585.         Level->site[x][y].p_locf = L_LAVA;
  586.       }
  587.       else if (Current_Environment == E_ASTRAL) {
  588.         if (Level->depth == 1) {
  589.           Level->site[x][y].locchar = RUBBLE;
  590.           Level->site[x][y].p_locf = L_RUBBLE;
  591.         }
  592.         else if (Level->depth == 2) {
  593.           Level->site[x][y].locchar = FIRE;
  594.           Level->site[x][y].p_locf = L_FIRE;
  595.         }
  596.         else if (Level->depth == 3) {
  597.           Level->site[x][y].locchar = WATER;
  598.           Level->site[x][y].p_locf = L_WATER;
  599.         }
  600.         else if (Level->depth == 4) {
  601.           Level->site[x][y].locchar = ABYSS;
  602.           Level->site[x][y].p_locf = L_ABYSS;
  603.         }
  604.       }
  605.       else {
  606.         Level->site[x][y].locchar = WATER;
  607.         Level->site[x][y].p_locf = L_WATER;
  608.       }
  609.     }
  610.       }
  611. }
  612.  
  613.  
  614.